<!doctype html>
<html lang="zh-CN">
<head>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    <meta name="referrer" content="no-referrer-when-downgrade">
    

    <title>《Dart语言基础之设计模式》 | 早起的年轻人</title>
    <meta property="og:title" content="《Dart语言基础之设计模式》 - 早起的年轻人">
    <meta property="og:type" content="article">
        
    <meta property="article:published_time" content='2021-07-28T19:39:10&#43;08:00'>
        
        
    <meta property="article:modified_time" content='2021-07-28T19:39:10&#43;08:00'>
        
    <meta name="Keywords" content="Flutter，golang,go语言,go语言笔记,飞雪无情,java,android,博客,项目管理,python,软件架构,公众号,小程序">
    <meta name="description" content="《Dart语言基础之设计模式》">
        
    <meta name="author" content="luckly">
    <meta property="og:url" content="https://luckly.work/post/dart/dart%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80%E4%B9%8B%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">
    <link rel="shortcut icon" href='/favicon.ico'  type="image/x-icon">

    <link rel="stylesheet" href='/css/normalize.css'>
    <link rel="stylesheet" href='/css/style.css'>
    <script type="text/javascript" src="//cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

    
    
    
        <link href="https://cdn.bootcdn.net/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.css" rel="stylesheet">
    
    
    
    
        <link rel="stylesheet" href='/css/douban.css'>
    
        <link rel="stylesheet" href='/css/other.css'>
    
</head>

<link rel="stylesheet"
      href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.2.0/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.2.0/highlight.min.js"></script>
<body>
    <header id="header" class="clearfix">
    <div class="container">
        <div class="col-group">
            <div class="site-name ">
                
                    <a id="logo" href="https://luckly.work/">
                        早起的年轻人
                    </a>
                
                <p class="description">专注于Flutter、Android、Java、Go语言(golang)、移动互联网、项目管理、软件架构</p>
            </div>
            <div>
                <nav id="nav-menu" class="clearfix">
                    <a class="current" href="https://luckly.work/">首页</a>
                    
                    <a  href="https://luckly.work/categories/" title="分类">分类</a>
                    
                    <a  href="https://luckly.work/tags/" title="标签">标签</a>
                    
                    <a  href="https://luckly.work/archives/" title="归档">归档</a>
                    
                    <a  href="https://luckly.work/about/" title="关于我">关于我</a>
                    
                    <a  href="https://github.com/ITmxs/" title="github">github</a>
                    
                </nav>
            </div>
        </div>
    </div>
</header>

    <div id="body">
        <div class="container">
            <div class="col-group">

                <div class="col-8" id="main">
                    
<div class="res-cons">
    <style type="text/css">
    .post-toc {
        position: fixed;
        width: 200px;
        margin-left: -210px;
        padding: 5px 10px;
        font-family: Athelas, STHeiti, Microsoft Yahei, serif;
        font-size: 12px;
        border: 1px solid rgba(0, 0, 0, .07);
        border-radius: 5px;
        background-color: rgba(255, 255, 255, 0.98);
        background-clip: padding-box;
        -webkit-box-shadow: 1px 1px 2px rgba(0, 0, 0, .125);
        box-shadow: 1px 1px 2px rgba(0, 0, 0, .125);
        word-wrap: break-word;
        white-space: nowrap;
        -webkit-box-sizing: border-box;
        box-sizing: border-box;
        z-index: 999;
        cursor: pointer;
        max-height: 70%;
        overflow-y: auto;
        overflow-x: hidden;
    }

    .post-toc .post-toc-title {
        width: 100%;
        margin: 0 auto;
        font-size: 20px;
        font-weight: 400;
        text-transform: uppercase;
        text-align: center;
    }

    .post-toc .post-toc-content {
        font-size: 15px;
    }

    .post-toc .post-toc-content>nav>ul {
        margin: 10px 0;
    }

    .post-toc .post-toc-content ul {
        padding-left: 20px;
        list-style: square;
        margin: 0.5em;
        line-height: 1.8em;
    }

    .post-toc .post-toc-content ul ul {
        padding-left: 15px;
        display: none;
    }

    @media print,
    screen and (max-width:1057px) {
        .post-toc {
            display: none;
        }
    }
</style>
<div class="post-toc" style="position: absolute; top: 188px;">
    <h2 class="post-toc-title">文章目录</h2>
    <div class="post-toc-content">
        <nav id="TableOfContents">
  <ul>
    <li><a href="#六大原则">六大原则</a>
      <ul>
        <li><a href="#开闭原则open-closed-principle">开闭原则(Open-Closed-Principle)</a></li>
        <li><a href="#里氏代换原则liskow-substitution-principle">里氏代换原则(Liskow-Substitution-Principle)</a></li>
        <li><a href="#依赖倒转原则dependency-inversion-principle">依赖倒转原则(Dependency-Inversion-Principle)</a></li>
        <li><a href="#单一职责原则single-responsibility-principle">单一职责原则(Single-Responsibility-Principle)</a></li>
        <li><a href="#接口隔离原则interface-segregation-principle">接口隔离原则(Interface-Segregation-Principle)</a></li>
        <li><a href="#迪米特法则law-of-demeter">迪米特法则(Law-Of-Demeter)</a></li>
      </ul>
    </li>
    <li><a href="#工厂模式">工厂模式</a>
      <ul>
        <li><a href="#模式分析">模式分析</a></li>
        <li><a href="#模式难点">模式难点</a></li>
        <li><a href="#模式解决问题">模式解决问题</a></li>
        <li><a href="#优点">优点</a></li>
        <li><a href="#缺点">缺点</a></li>
        <li><a href="#模式应用场景">模式应用场景</a></li>
        <li><a href="#模式代码">模式代码</a></li>
      </ul>
    </li>
    <li><a href="#单例模式">单例模式</a>
      <ul>
        <li><a href="#模式分析-1">模式分析</a></li>
        <li><a href="#模式解决问题-1">模式解决问题</a></li>
        <li><a href="#优点-1">优点</a></li>
        <li><a href="#缺点-1">缺点</a></li>
        <li><a href="#模式应用场景-1">模式应用场景</a></li>
        <li><a href="#模式代码-1">模式代码</a></li>
      </ul>
    </li>
    <li><a href="#建造者模式">建造者模式</a>
      <ul>
        <li><a href="#模式分析-2">模式分析</a></li>
        <li><a href="#模式难点-1">模式难点</a></li>
        <li><a href="#模式解决问题-2">模式解决问题</a></li>
        <li><a href="#优点-2">优点</a></li>
        <li><a href="#缺点-2">缺点</a></li>
        <li><a href="#模式应用场景-2">模式应用场景</a></li>
        <li><a href="#模式代码-2">模式代码</a></li>
      </ul>
    </li>
    <li><a href="#原型模式">原型模式</a>
      <ul>
        <li><a href="#模式分析-3">模式分析</a></li>
        <li><a href="#模式解决问题-3">模式解决问题</a></li>
        <li><a href="#模式难点-2">模式难点</a></li>
        <li><a href="#优点-3">优点</a></li>
        <li><a href="#缺点-3">缺点</a></li>
        <li><a href="#模式应用场景-3">模式应用场景</a></li>
        <li><a href="#模式代码-3">模式代码</a></li>
      </ul>
    </li>
    <li><a href="#适配器模式">适配器模式</a>
      <ul>
        <li><a href="#模式分析-4">模式分析</a></li>
        <li><a href="#模式难点-3">模式难点</a></li>
        <li><a href="#模式解决问题-4">模式解决问题</a></li>
        <li><a href="#优点-4">优点</a></li>
        <li><a href="#缺点-4">缺点</a></li>
        <li><a href="#模式应用场景-4">模式应用场景</a></li>
        <li><a href="#模式代码-4">模式代码</a></li>
      </ul>
    </li>
    <li><a href="#桥接模式bridge">桥接模式(Bridge)</a>
      <ul>
        <li><a href="#模式分析-5">模式分析</a></li>
        <li><a href="#模式难点-4">模式难点</a></li>
        <li><a href="#模式解决问题-5">模式解决问题</a></li>
        <li><a href="#优点-5">优点</a></li>
        <li><a href="#缺点-5">缺点</a></li>
        <li><a href="#模式应用场景-5">模式应用场景</a></li>
        <li><a href="#模式代码-5">模式代码</a></li>
      </ul>
    </li>
    <li><a href="#装饰器模式decorator-pattern">装饰器模式(Decorator Pattern)</a>
      <ul>
        <li><a href="#模式分析-6">模式分析</a></li>
        <li><a href="#模式难点-5">模式难点</a></li>
        <li><a href="#模式解决问题-6">模式解决问题</a></li>
        <li><a href="#优点-6">优点</a></li>
        <li><a href="#缺点-6">缺点</a></li>
        <li><a href="#模式应用场景-6">模式应用场景</a></li>
        <li><a href="#模式代码-6">模式代码</a></li>
      </ul>
    </li>
    <li><a href="#外观模式facade">外观模式(Facade)</a>
      <ul>
        <li><a href="#模式分析-7">模式分析</a></li>
        <li><a href="#模式难点-6">模式难点</a></li>
        <li><a href="#模式解决问题-7">模式解决问题</a></li>
        <li><a href="#优点-7">优点</a></li>
        <li><a href="#缺点-7">缺点</a></li>
        <li><a href="#模式应用场景-7">模式应用场景</a></li>
        <li><a href="#模式代码-7">模式代码</a></li>
      </ul>
    </li>
    <li><a href="#享元模式flyweight">享元模式(Flyweight)</a>
      <ul>
        <li><a href="#模式分析-8">模式分析</a></li>
        <li><a href="#模式难点-7">模式难点</a></li>
        <li><a href="#模式解决问题-8">模式解决问题</a></li>
        <li><a href="#优点-8">优点</a></li>
        <li><a href="#缺点-8">缺点</a></li>
        <li><a href="#模式应用场景-8">模式应用场景</a></li>
        <li><a href="#模式代码-8">模式代码</a></li>
      </ul>
    </li>
    <li><a href="#代理模式">代理模式</a>
      <ul>
        <li><a href="#模式分析-9">模式分析</a></li>
        <li><a href="#模式难点-8">模式难点</a></li>
        <li><a href="#模式解决问题-9">模式解决问题</a></li>
        <li><a href="#优点-9">优点</a></li>
        <li><a href="#缺点-9">缺点</a></li>
        <li><a href="#模式应用场景-9">模式应用场景</a></li>
        <li><a href="#模式代码-9">模式代码</a></li>
      </ul>
    </li>
    <li><a href="#发布订阅模式">发布订阅模式</a>
      <ul>
        <li><a href="#模式分析-10">模式分析</a></li>
        <li><a href="#模式难点-9">模式难点</a></li>
        <li><a href="#模式解决问题-10">模式解决问题</a></li>
        <li><a href="#优点-10">优点</a></li>
        <li><a href="#缺点-10">缺点</a></li>
        <li><a href="#模式应用场景-10">模式应用场景</a></li>
        <li><a href="#模式代码-10">模式代码</a></li>
      </ul>
    </li>
  </ul>
</nav>
    </div>
</div>
<script type="text/javascript">
    $(document).ready(function () {
        var postToc = $(".post-toc");
        if (postToc.length) {
            var leftPos = $("#main").offset().left;
            if(leftPos<220){
                postToc.css({"width":leftPos-10,"margin-left":(0-leftPos)})
            }

            var t = postToc.offset().top - 20,
                a = {
                    start: {
                        position: "absolute",
                        top: t
                    },
                    process: {
                        position: "fixed",
                        top: 20
                    },
                };
            $(window).scroll(function () {
                var e = $(window).scrollTop();
                e < t ? postToc.css(a.start) : postToc.css(a.process)
            })
        }
    })
</script>
    <article class="post">
        <header>
            <h1 class="post-title">《Dart语言基础之设计模式》</h1>
        </header>
        <date class="post-meta meta-date">
            2021年7月28日
        </date>
        
        <div class="post-meta">
            <span>|</span>
            
            <span class="meta-category"><a href='/categories/Flutter'>Flutter</a></span>
            
        </div>
        
        
        <div class="post-meta">
            <span id="busuanzi_container_page_pv">|<span id="busuanzi_value_page_pv"></span><span>
                    阅读</span></span>
        </div>
        
        
        <div class="clear" style="display: none">
            <div class="toc-article">
                <div class="toc-title">文章目录</div>
            </div>
        </div>
        
        <div class="post-content">
            <blockquote>
<p>本文主要介绍</p>
</blockquote>
<h1 id="设计模式">设计模式</h1>
<p><a href="https://www.runoob.com/design-pattern/">参考</a> 模式分析，模式难点，模式解决问题，优点，缺点，模式应用场景，模式代码(基于dart)</p>
<h2 id="六大原则">六大原则</h2>
<h3 id="开闭原则open-closed-principle">开闭原则(Open-Closed-Principle)</h3>
<p>核心：一个软件实体应当对拓展开放，对修改关闭。即：软件实体应尽量在不修改原有代码的情况下进行拓展。</p>
<h3 id="里氏代换原则liskow-substitution-principle">里氏代换原则(Liskow-Substitution-Principle)</h3>
<p>核心：所有引用基类(父类)的地方，都必须能透明地使用其子类的对象。</p>
<p>一个软件实体如果使用的是一个父类，那么一定适用于其子类，而且他察觉不出父类对象和子类对象的区别。也就是说，在软件里面，把父类都替换成它的子类，程序的行为没有变化。简单地说，子类必须能够替换掉它们的父类型。</p>
<h3 id="依赖倒转原则dependency-inversion-principle">依赖倒转原则(Dependency-Inversion-Principle)</h3>
<p>核心: 抽象不应该依赖于细节，细节应当依赖于抽象。换言之，要针对接口编程，而非针对实现编程。</p>
<p>思想: 抽象不应该依赖于细节，细节应当依赖于抽象。换言之，要针对接口编程，而不是针对实现编程。依赖倒转其实可以说是面向对象设计的标志，用哪种语言来编写程序不重要，如果编写时考虑的都是如何针对抽象编程而不是针对细节编程，即 程序中所有的依赖关系都是终止于抽象类或者接口，那就是面向对象的设计，反之就是面向过程化设计了。</p>
<p>原则：</p>
<ol>
<li>高层模块不应该依赖于低层模块。两个都应该依赖于抽象。</li>
<li>抽象不应该依赖细节。细节应该依赖于抽象。</li>
</ol>
<h3 id="单一职责原则single-responsibility-principle">单一职责原则(Single-Responsibility-Principle)</h3>
<p>核心：一个类只负责一个功能领域中相应的职责，或者可以定义为：就一个类而言，应该只有一个引起它变化的原因。</p>
<p>思想：如果一个类承担的职责过多，就等于把这些职责耦合在一起，一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计，当变化发生时，设计会遭受到意想不到的破坏。【Eg:游戏的界面组成与逻辑组成分离】</p>
<h3 id="接口隔离原则interface-segregation-principle">接口隔离原则(Interface-Segregation-Principle)</h3>
<p>核心：使用多个专门的接口，而不使用单一的总接口。即 客户端不应该依赖于那些它不需要的接口。</p>
<h3 id="迪米特法则law-of-demeter">迪米特法则(Law-Of-Demeter)</h3>
<p>核心：一个软件实体应当尽可能少地与其他实体发生作用。(无熟人难办事)</p>
<p>思想：也叫最少知识原则。如果两个类不彼此通信，那么这两个类就不应当直接地发生相互作用。如果其中一个类需要另一个类的某一个方法的话，可以通过第三者转发这个调用。(不要和陌生人说话)</p>
<p>原则： 在迪米特法则中，对于一个对象，其朋友包括如下几类：</p>
<ol>
<li>当前对象 this</li>
<li>以参数形式传入到当前对象方法中的对象</li>
<li>当前对象的成员对象</li>
<li>若当前对象的成员你对象是一个集合，那么集合中的对象也都是朋友</li>
<li>当前对象所创建的对象</li>
</ol>
<h2 id="工厂模式">工厂模式</h2>
<h3 id="模式分析">模式分析</h3>
<p>定义一个创建对象的接口，让其子类自己决定实例化哪一个工厂类，工厂模式使其创建过程延迟到子类进行</p>
<h3 id="模式难点">模式难点</h3>
<h3 id="模式解决问题">模式解决问题</h3>
<p>该模式主要解决接口选择的问题。我们明确地计划不同条件下创建不同实例时，让其子类实现工厂接口，返回的也是一个抽象的产品</p>
<h3 id="优点">优点</h3>
<ol>
<li>一个调用者想创建一个对象，只要知道其名称就可以了。</li>
<li>扩展性高，如果想增加一个产品，只要扩展一个工厂类就可以。</li>
<li>屏蔽产品的具体实现，调用者只关心产品的接口。</li>
</ol>
<h3 id="缺点">缺点</h3>
<p>每次增加一个产品时，都需要增加一个具体类和对象实现工厂，使得系统中类的个数成倍增加，在一定程度上增加了系统的复杂度，同时也增加了系统具体类的依赖。</p>
<h3 id="模式应用场景">模式应用场景</h3>
<ol>
<li>日志记录器：记录可能记录到本地硬盘、系统事件、远程服务器等，用户可以选择记录日志到什么地方。</li>
<li>数据库访问，当用户不知道最后系统采用哪一类数据库，以及数据库可能有变化时。</li>
<li>设计一个连接服务器的框架，需要三个协议，&ldquo;POP3&rdquo;、&ldquo;IMAP&rdquo;、&ldquo;HTTP&rdquo;，可以把这三个作为产品类，共同实现一个接口。</li>
</ol>
<h3 id="模式代码">模式代码</h3>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-dart" data-lang="dart"><span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Pen</span> {
  draw();
}

<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Pencil</span> <span style="color:#66d9ef">implements</span> Pen {
  draw() {
    print(<span style="color:#e6db74">&#34;this is Pencil&#34;</span>);
  }
}

<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">ColorPen</span> <span style="color:#66d9ef">implements</span> Pen {
  draw() {
    print(<span style="color:#e6db74">&#34;this is ColorPen&#34;</span>);
  }
}
<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">RunFactory</span> <span style="color:#66d9ef">implements</span> Run {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  main() {
    <span style="color:#66d9ef">var</span> pencil <span style="color:#f92672">=</span> getPen(<span style="color:#e6db74">&#34;Pencil&#34;</span>);
    <span style="color:#66d9ef">var</span> colorPen <span style="color:#f92672">=</span> getPen(<span style="color:#e6db74">&#34;ColorPen&#34;</span>);
    pencil.draw();
    colorPen.draw();
  }
  Pen getPen(<span style="color:#66d9ef">String</span> penStr) {
    <span style="color:#66d9ef">if</span> (penStr <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;Pencil&#34;</span>) {
      <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> Pencil();
    } <span style="color:#66d9ef">else</span> <span style="color:#66d9ef">if</span> (penStr <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;ColorPen&#34;</span>) {
      <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> ColorPen();
    } <span style="color:#66d9ef">else</span> {
      <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">null</span>;
    }
  }
}
</code></pre></div><h2 id="单例模式">单例模式</h2>
<blockquote>
<p>这种类型的设计模式属于创建型模式，它提供了一种创建对象的最佳方式。</p>
</blockquote>
<blockquote>
<p>这种模式涉及到一个单一的类，该类负责创建自己的对象，同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式，可以直接访问，不需要实例化该类的对象。</p>
</blockquote>
<h3 id="模式分析-1">模式分析</h3>
<ol>
<li>单例类只能有一个实例。</li>
<li>单例类必须自己创建自己的唯一实例。</li>
<li>单例类必须给所有其他对象提供这一实例。</li>
</ol>
<h3 id="模式解决问题-1">模式解决问题</h3>
<ol>
<li>控制实例数目，节省系统资源。</li>
<li>保证该类只有一个实例，多处共享</li>
</ol>
<h3 id="优点-1">优点</h3>
<ol>
<li>内存中只有一个实例，减少了内存开销，尤其是频繁创建和销毁实例</li>
<li>避免对资源的多重占用</li>
<li>保证全局唯一实例从而保证实例状态一致</li>
</ol>
<h3 id="缺点-1">缺点</h3>
<ol>
<li>没有接口，不能继承</li>
<li>大量使用也会导致内存泄漏</li>
</ol>
<h3 id="模式应用场景-1">模式应用场景</h3>
<ol>
<li>要求生产唯一序列号。</li>
<li>WEB 中的计数器，不用每次刷新都在数据库里加一次，用单例先缓存起来。</li>
<li>创建的一个对象需要消耗的资源过多，比如 I/O 与数据库的连接等。</li>
</ol>
<h3 id="模式代码-1">模式代码</h3>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-dart" data-lang="dart"><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">_SingleTon</span> {
  _SingleTon._();
  <span style="color:#75715e">//第一种方式调用
</span><span style="color:#75715e"></span>  <span style="color:#66d9ef">factory</span> _SingleTon() {
    <span style="color:#66d9ef">return</span> instance;
  }
  <span style="color:#75715e">//第二种方式调用
</span><span style="color:#75715e"></span>  <span style="color:#66d9ef">static</span> _SingleTon instance <span style="color:#f92672">=</span> _SingleTon._();
  <span style="color:#66d9ef">int</span> count <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>;
}

<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">RunSingleTon</span> <span style="color:#66d9ef">implements</span> Run {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  main() {
    print(<span style="color:#e6db74">&#39;单例模式创建&#39;</span>);
    print(_SingleTon().count<span style="color:#f92672">++</span>);
    print(_SingleTon.instance.count<span style="color:#f92672">++</span>);
    print(_SingleTon.instance.count<span style="color:#f92672">++</span>);
  }
}
</code></pre></div><h2 id="建造者模式">建造者模式</h2>
<h3 id="模式分析-2">模式分析</h3>
<p>建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式，它提供了一种创建对象的最佳方式。</p>
<p>一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。</p>
<h3 id="模式难点-1">模式难点</h3>
<p>如何抽象出不同特性需要很强的抽象思维</p>
<h3 id="模式解决问题-2">模式解决问题</h3>
<p>主要解决在软件系统中，有时候面临着&quot;一个复杂对象&quot;的创建工作，其通常由各个部分的子对象用一定的算法构成；由于需求的变化，这个复杂对象的各个部分经常面临着剧烈的变化，但是将它们组合在一起的算法却相对稳定。</p>
<h3 id="优点-2">优点</h3>
<ol>
<li>建造者独立，易扩展。</li>
<li>便于控制细节风险。</li>
</ol>
<h3 id="缺点-2">缺点</h3>
<ol>
<li>产品必须有共同点，范围有限制。</li>
<li>如内部变化复杂，会有很多的建造类。</li>
</ol>
<h3 id="模式应用场景-2">模式应用场景</h3>
<ol>
<li>需要生成的对象具有复杂的内部结构。</li>
<li>需要生成的对象内部属性本身相互依赖。</li>
</ol>
<h3 id="模式代码-2">模式代码</h3>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-dart" data-lang="dart"><span style="color:#75715e">//建造者模式
</span><span style="color:#75715e"></span>
<span style="color:#66d9ef">import</span> <span style="color:#e6db74">&#39;run.dart&#39;</span>;

<span style="color:#75715e">//建造者模式的精髓在于抽象，要把内容都抽象成一个一个的类来实现
</span><span style="color:#75715e">//标识食物的接口
</span><span style="color:#75715e"></span><span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Item</span> {
  <span style="color:#66d9ef">String</span> name;
  Packing packing();
  <span style="color:#66d9ef">double</span> price;
}

<span style="color:#75715e">//包装接口
</span><span style="color:#75715e"></span><span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Packing</span> {
  <span style="color:#66d9ef">String</span> pack();
}

<span style="color:#75715e">//实现包装接口的实体类
</span><span style="color:#75715e"></span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Wrapper</span> <span style="color:#66d9ef">implements</span> Packing {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  pack() {
    <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;Wrapper&#34;</span>;
  }
}

<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Bottle</span> <span style="color:#66d9ef">implements</span> Packing {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">String</span> pack() {
    <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;Bottle&#34;</span>;
  }
}

<span style="color:#75715e">///创建实现Item接口的抽象类
</span><span style="color:#75715e">//使用包装纸包装的食物
</span><span style="color:#75715e"></span><span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Burger</span> <span style="color:#66d9ef">implements</span> Item {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  Packing packing() {
    <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> Wrapper();
  }
}
<span style="color:#75715e">//使用瓶子包装的食物
</span><span style="color:#75715e"></span><span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">ColdDrink</span> <span style="color:#66d9ef">implements</span> Item {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  Packing packing() {
    <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> Bottle();
  }
}

<span style="color:#75715e">//创建扩展了Burger和ColdDrink的实体类
</span><span style="color:#75715e">//蔬菜
</span><span style="color:#75715e"></span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">VegBurger</span> <span style="color:#66d9ef">extends</span> Burger {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">String</span> name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;Veg Burger&#34;</span>;

  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">double</span> price <span style="color:#f92672">=</span> <span style="color:#ae81ff">34.3</span>;
}

<span style="color:#75715e">//鸡肉汉堡包
</span><span style="color:#75715e"></span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">ChickenBurger</span> <span style="color:#66d9ef">extends</span> Burger {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">String</span> name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;Chicken Burger&#34;</span>;
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">double</span> price <span style="color:#f92672">=</span> <span style="color:#ae81ff">56.2</span>;
}

<span style="color:#75715e">//可乐
</span><span style="color:#75715e"></span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Coke</span> <span style="color:#66d9ef">extends</span> ColdDrink {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">String</span> name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;Coke&#34;</span>;
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">double</span> price <span style="color:#f92672">=</span> <span style="color:#ae81ff">3</span>;
}

<span style="color:#75715e">//百事
</span><span style="color:#75715e"></span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Pepsi</span> <span style="color:#66d9ef">extends</span> ColdDrink {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">String</span> name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;Pepsi&#34;</span>;
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">double</span> price <span style="color:#f92672">=</span> <span style="color:#ae81ff">4</span>;
}

<span style="color:#75715e">//创建Meal类用于打印实例化的对象信息
</span><span style="color:#75715e"></span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Meal</span> {
  List<span style="color:#f92672">&lt;</span>Item<span style="color:#f92672">&gt;</span> _items <span style="color:#f92672">=</span> [];
  <span style="color:#66d9ef">void</span> addItem(Item item) <span style="color:#f92672">=&gt;</span> _items.add(item);
  <span style="color:#75715e">//计算所有项目的总价
</span><span style="color:#75715e"></span>  <span style="color:#66d9ef">double</span> getCost() {
    <span style="color:#66d9ef">double</span> cost <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>;
    <span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">var</span> item <span style="color:#66d9ef">in</span> _items) {
      cost <span style="color:#f92672">+=</span> item.price;
    }
    <span style="color:#66d9ef">return</span> cost;
  }

  <span style="color:#75715e">//展示当前项目
</span><span style="color:#75715e"></span>  showItems() {
    <span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">var</span> item <span style="color:#66d9ef">in</span> _items) {
      print(<span style="color:#e6db74">&#34;item:&#34;</span> <span style="color:#f92672">+</span>
          item.name <span style="color:#f92672">+</span>
          <span style="color:#e6db74">&#34;, Packing: &#34;</span> <span style="color:#f92672">+</span>
          item.packing().pack() <span style="color:#f92672">+</span>
          <span style="color:#e6db74">&#34;, Price:&#34;</span> <span style="color:#f92672">+</span>
          item.price.toString());
    }
  }
}

<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">MealBuilder</span> {
  Meal prepareVegMeal() {
    Meal meal <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> Meal();
    meal.addItem(<span style="color:#66d9ef">new</span> VegBurger());
    meal.addItem(<span style="color:#66d9ef">new</span> Coke());
    <span style="color:#66d9ef">return</span> meal;
  }

  Meal prepareNonVegMeal() {
    Meal meal <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> Meal();
    meal.addItem(<span style="color:#66d9ef">new</span> ChickenBurger());
    meal.addItem(<span style="color:#66d9ef">new</span> Pepsi());
    <span style="color:#66d9ef">return</span> meal;
  }
}

<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">RunBuilderPattern</span> <span style="color:#66d9ef">implements</span> Run {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  main() {
    print(<span style="color:#e6db74">&#39;建造者模式创建&#39;</span>);
    MealBuilder mealBuilder <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> MealBuilder();
    Meal vegMeal <span style="color:#f92672">=</span> mealBuilder.prepareVegMeal();
    print(<span style="color:#e6db74">&#34;Veg Meal&#34;</span>);
    vegMeal.showItems();
    print(<span style="color:#e6db74">&#34;Total Cost: &#34;</span> <span style="color:#f92672">+</span> vegMeal.getCost().toString());

    Meal nonVegMeal <span style="color:#f92672">=</span> mealBuilder.prepareNonVegMeal();
    print(<span style="color:#e6db74">&#34;</span><span style="color:#ae81ff">\n\n</span><span style="color:#e6db74">Non-Veg Meal&#34;</span>);
    nonVegMeal.showItems();
    print(<span style="color:#e6db74">&#34;Total Cost: &#34;</span> <span style="color:#f92672">+</span> nonVegMeal.getCost().toString());
  }
}
</code></pre></div><h2 id="原型模式">原型模式</h2>
<h3 id="模式分析-3">模式分析</h3>
<p>原型模式(Prototype Pattern)是用于创建<code>重复的对象</code>，同时又能保证性能。这种类型的设计模式属于<code>创建型模式</code>，它提供了一种创建对象的最佳方式。</p>
<p>这种模式是实现了一个原型接口，该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时，则采用这种模式。例如，一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象，在下一个请求时返回它的克隆，在需要的时候更新数据库，以此来减少数据库调用。</p>
<h3 id="模式解决问题-3">模式解决问题</h3>
<ol>
<li>当一个系统应该独立于它的产品创建，构成和表示时。</li>
<li>当要实例化的类是在运行时刻指定时，例如，通过动态装载。</li>
<li>为了避免创建一个与产品类层次平行的工厂类层次时。</li>
<li>当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。</li>
</ol>
<h3 id="模式难点-2">模式难点</h3>
<p>克隆</p>
<h3 id="优点-3">优点</h3>
<ol>
<li>性能提高。</li>
<li>逃避构造函数的约束。</li>
</ol>
<h3 id="缺点-3">缺点</h3>
<ol>
<li>配备克隆方法需要对类的功能进行通盘考虑，这对于全新的类不是很难，但对于已有的类不一定很容易，特别当一个类引用不支持串行化的间接对象，或者引用含有循环结构的时候。</li>
<li>必须实现 Cloneable 接口。</li>
</ol>
<h3 id="模式应用场景-3">模式应用场景</h3>
<ol>
<li>资源优化场景。</li>
<li>类初始化需要消化非常多的资源，这个资源包括数据、硬件资源等。</li>
<li>性能和安全要求的场景。</li>
<li>通过 new 产生一个对象需要非常繁琐的数据准备或访问权限，则可以使用原型模式。</li>
<li>一个对象多个修改者的场景。</li>
<li>一个对象需要提供给其他对象访问，而且各个调用者可能都需要修改其值时，可以考虑使用原型模式拷贝多个对象供调用者使用。</li>
<li>在实际项目中，原型模式很少单独出现，一般是和工厂方法模式一起出现，通过 clone 的方法创建一个对象，然后由工厂方法提供给调用者。原型模式已经与 Java 融为浑然一体，大家可以随手拿来使用。</li>
</ol>
<h3 id="模式代码-3">模式代码</h3>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-dart" data-lang="dart"><span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">ProtoType</span>{
  <span style="color:#66d9ef">String</span> _id;
  ProtoType(<span style="color:#66d9ef">this</span>._id);
  <span style="color:#66d9ef">String</span> <span style="color:#66d9ef">get</span> id<span style="color:#f92672">=&gt;</span>_id;
  <span style="color:#66d9ef">void</span> <span style="color:#66d9ef">set</span> id(<span style="color:#66d9ef">String</span> id)<span style="color:#f92672">=&gt;</span><span style="color:#66d9ef">this</span>._id<span style="color:#f92672">=</span>id;
  ProtoType clone();
}
<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">ConcretePrototype</span> <span style="color:#66d9ef">extends</span> ProtoType{
  ConcretePrototype(<span style="color:#66d9ef">String</span> id,<span style="color:#66d9ef">this</span>.name) <span style="color:#f92672">:</span> <span style="color:#66d9ef">super</span>(id);
  <span style="color:#66d9ef">final</span> <span style="color:#66d9ef">String</span> name;
  <span style="color:#960050;background-color:#1e0010">@</span>override
  ConcretePrototype clone() {
    ProtoType protoType <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> ConcretePrototype(<span style="color:#66d9ef">this</span>.id,<span style="color:#66d9ef">this</span>.name);
    <span style="color:#66d9ef">return</span> protoType;
  }
}
<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">RunPrototype</span> <span style="color:#66d9ef">implements</span> Run {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  main(){
    <span style="color:#66d9ef">var</span> a<span style="color:#f92672">=</span> ConcretePrototype(<span style="color:#e6db74">&#34;1&#34;</span>,<span style="color:#e6db74">&#34;protoType模式&#34;</span>);
    <span style="color:#66d9ef">var</span> b<span style="color:#f92672">=</span> a.clone();
    print(<span style="color:#e6db74">&#34;实例a的hashCode:&#34;</span><span style="color:#f92672">+</span>a.hashCode.toString());
    print(<span style="color:#e6db74">&#34;实例b的hashCode:&#34;</span><span style="color:#f92672">+</span>b.hashCode.toString());
    print(<span style="color:#e6db74">&#34;实例a的name:&#34;</span><span style="color:#f92672">+</span>a.name);
    print(<span style="color:#e6db74">&#34;实例b的name:&#34;</span><span style="color:#f92672">+</span>b.name);
  }
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">String</span> name<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;原型模式&#34;</span>;
}
</code></pre></div><h2 id="适配器模式">适配器模式</h2>
<h3 id="模式分析-4">模式分析</h3>
<p>适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式，它结合了两个独立接口的功能。 这种模式涉及到一个单一的类，该类负责加入独立的或不兼容的接口功能。举个真实的例子，读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器，再将读卡器插入笔记本，这样就可以通过笔记本来读取内存卡。 我们通过下面的实例来演示适配器模式的使用。其中，音频播放器设备只能播放 mp3 文件，通过使用一个更高级的音频播放器来播放 vlc 和 mp4 文件。</p>
<h3 id="模式难点-3">模式难点</h3>
<h3 id="模式解决问题-4">模式解决问题</h3>
<p>主要解决在软件系统中，常常要将一些&quot;现存的对象&quot;放到新的环境中，而新环境要求的接口是现对象不能满足的。</p>
<h3 id="优点-4">优点</h3>
<ol>
<li>可以让任何两个没有关联的类一起运行。</li>
<li>提高了类的复用。</li>
<li>增加了类的透明度。</li>
<li>灵活性好。</li>
</ol>
<h3 id="缺点-4">缺点</h3>
<ol>
<li>过多地使用适配器，会让系统非常零乱，不易整体进行把握。比如，明明看到调用的是 A 接口，其实内部被适配成了 B 接口的实现，一个系统如果太多出现这种情况，无异于一场灾难。因此如果不是很有必要，可以不使用适配器，而是直接对系统进行重构。 2.由于 JAVA 至多继承一个类，所以至多只能适配一个适配者类，而且目标类必须是抽象类。</li>
</ol>
<h3 id="模式应用场景-4">模式应用场景</h3>
<p>有动机地修改一个正常运行的系统的接口，这时应该考虑使用适配器模式。</p>
<h3 id="模式代码-4">模式代码</h3>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-dart" data-lang="dart"><span style="color:#66d9ef">import</span> <span style="color:#e6db74">&#39;run.dart&#39;</span>;

<span style="color:#75715e">//官方媒体播放接口
</span><span style="color:#75715e"></span><span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">MediaPlayer</span> {
  <span style="color:#66d9ef">void</span> play(<span style="color:#66d9ef">String</span> audioType, <span style="color:#66d9ef">String</span> fileName);
}

<span style="color:#75715e">//自定义媒体播放接口
</span><span style="color:#75715e"></span><span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">AdvancedMediaPlayer</span> {
  <span style="color:#66d9ef">void</span> playVlc(<span style="color:#66d9ef">String</span> fileName);
  <span style="color:#66d9ef">void</span> playMp4(<span style="color:#66d9ef">String</span> fileName);
}

<span style="color:#75715e">//创建实现了 AdvancedMediaPlayer 接口的实体类。
</span><span style="color:#75715e"></span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">VlcPlayer</span> <span style="color:#66d9ef">implements</span> AdvancedMediaPlayer {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> playMp4(<span style="color:#66d9ef">String</span> fileName) {}

  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> playVlc(<span style="color:#66d9ef">String</span> fileName) {
    print(<span style="color:#e6db74">&#34;Playing vlc file. Name: &#34;</span> <span style="color:#f92672">+</span> fileName);
  }
}

<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Mp4Player</span> <span style="color:#66d9ef">implements</span> AdvancedMediaPlayer {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> playVlc(<span style="color:#66d9ef">String</span> fileName) {
    <span style="color:#75715e">//什么也不做
</span><span style="color:#75715e"></span>  }

  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> playMp4(<span style="color:#66d9ef">String</span> fileName) {
    print(<span style="color:#e6db74">&#34;Playing mp4 file. Name: &#34;</span> <span style="color:#f92672">+</span> fileName);
  }
}

<span style="color:#75715e">// 创建实现了 MediaPlayer 接口的适配器类。
</span><span style="color:#75715e"></span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">MediaAdapter</span> <span style="color:#66d9ef">implements</span> MediaPlayer {
  AdvancedMediaPlayer advancedMusicPlayer;
  MediaAdapter(<span style="color:#66d9ef">String</span> audioType) {
    <span style="color:#66d9ef">if</span> (audioType <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;vlc&#34;</span>) {
      advancedMusicPlayer <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> VlcPlayer();
    } <span style="color:#66d9ef">else</span> <span style="color:#66d9ef">if</span> (audioType <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;mp4&#34;</span>) {
      advancedMusicPlayer <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> Mp4Player();
    }
  }
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> play(<span style="color:#66d9ef">String</span> audioType, <span style="color:#66d9ef">String</span> fileName) {
    <span style="color:#66d9ef">if</span> (audioType <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;vlc&#34;</span>) {
      advancedMusicPlayer.playVlc(fileName);
    } <span style="color:#66d9ef">else</span> <span style="color:#66d9ef">if</span> (audioType <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;mp4&#34;</span>) {
      advancedMusicPlayer.playMp4(fileName);
    }
  }
}

<span style="color:#75715e">// 创建实现了 MediaPlayer 接口的实体类。
</span><span style="color:#75715e"></span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">AudioPlayer</span> <span style="color:#66d9ef">implements</span> MediaPlayer {
  MediaAdapter mediaAdapter;

  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> play(<span style="color:#66d9ef">String</span> audioType, <span style="color:#66d9ef">String</span> fileName) {
    <span style="color:#75715e">//播放 mp3 音乐文件的内置支持
</span><span style="color:#75715e"></span>    <span style="color:#66d9ef">if</span> (audioType <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;mp3&#34;</span>) {
      print(<span style="color:#e6db74">&#34;Playing mp3 file. Name: &#34;</span> <span style="color:#f92672">+</span> fileName);
    }
    <span style="color:#75715e">//mediaAdapter 提供了播放其他文件格式的支持
</span><span style="color:#75715e"></span>    <span style="color:#66d9ef">else</span> <span style="color:#66d9ef">if</span> (audioType <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;vlc&#34;</span> <span style="color:#f92672">||</span> audioType <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;mp4&#34;</span>) {
      mediaAdapter <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> MediaAdapter(audioType);
      mediaAdapter.play(audioType, fileName);
    } <span style="color:#66d9ef">else</span> {
      print(<span style="color:#e6db74">&#34;Invalid media. &#34;</span> <span style="color:#f92672">+</span> audioType <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34; format not supported&#34;</span>);
    }
  }
}

<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">RunAdapter</span> <span style="color:#66d9ef">implements</span> Run {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  main() {
    AudioPlayer audioPlayer <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> AudioPlayer();
    audioPlayer.play(<span style="color:#e6db74">&#34;mp3&#34;</span>, <span style="color:#e6db74">&#34;beyond the horizon.mp3&#34;</span>);
    audioPlayer.play(<span style="color:#e6db74">&#34;mp4&#34;</span>, <span style="color:#e6db74">&#34;alone.mp4&#34;</span>);
    audioPlayer.play(<span style="color:#e6db74">&#34;vlc&#34;</span>, <span style="color:#e6db74">&#34;far far away.vlc&#34;</span>);
    audioPlayer.play(<span style="color:#e6db74">&#34;avi&#34;</span>, <span style="color:#e6db74">&#34;mind me.avi&#34;</span>);
  }

  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">String</span> name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;适配器模式&#34;</span>;
}
</code></pre></div><h2 id="桥接模式bridge">桥接模式(Bridge)</h2>
<h3 id="模式分析-5">模式分析</h3>
<p>桥接(Bridge)是用于把抽象化与实现化解耦，使得二者可以独立变化。这种类型的设计模式属于结构型模式，它通过提供抽象化和实现化之间的桥接结构，来实现二者的解耦。</p>
<p>这种模式涉及到一个作为桥接的接口，使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。</p>
<p>我们通过下面的实例来演示桥接模式(Bridge Pattern)的用法。其中，可以使用相同的抽象类方法但是不同的桥接实现类，来画出不同颜色的圆。</p>
<h3 id="模式难点-4">模式难点</h3>
<h3 id="模式解决问题-5">模式解决问题</h3>
<p>在有多种可能会变化的情况下，用继承会造成类爆炸问题，扩展起来不灵活。</p>
<h3 id="优点-5">优点</h3>
<ol>
<li>抽象和实现的分离。</li>
<li>优秀的扩展能力。</li>
<li>实现细节对客户透明。</li>
</ol>
<h3 id="缺点-5">缺点</h3>
<p>桥接模式的引入会增加系统的理解与设计难度，由于聚合关联关系建立在抽象层，要求开发者针对抽象进行设计与编程。</p>
<h3 id="模式应用场景-5">模式应用场景</h3>
<ol>
<li>如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性，避免在两个层次之间建立静态的继承联系，通过桥接模式可以使它们在抽象层建立一个关联关系。</li>
<li>对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统，桥接模式尤为适用。</li>
<li>一个类存在两个独立变化的维度，且这两个维度都需要进行扩展。</li>
</ol>
<h3 id="模式代码-5">模式代码</h3>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-dart" data-lang="dart"><span style="color:#75715e">//咖啡售卖系统中，容量作为抽象化(Abstraction)，口味作为实现化(Implementor)
</span><span style="color:#75715e">//创建口味接口
</span><span style="color:#75715e"></span><span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">ICoffeeAdditives</span> {
  <span style="color:#66d9ef">void</span> addSomething();
}

<span style="color:#75715e">// 创建抽象化类
</span><span style="color:#75715e"></span><span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Coffee</span> {
  ICoffeeAdditives additives;
  Coffee(<span style="color:#66d9ef">this</span>.additives);
  <span style="color:#66d9ef">void</span> orderCoffee(<span style="color:#66d9ef">int</span> count);
}

<span style="color:#75715e">//修正抽象化类，增加品控方法
</span><span style="color:#75715e"></span><span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">RefinedCoffee</span> <span style="color:#66d9ef">extends</span> Coffee {
  RefinedCoffee(ICoffeeAdditives additives) <span style="color:#f92672">:</span> <span style="color:#66d9ef">super</span>(additives);
  checkQuality(<span style="color:#66d9ef">int</span> score) {
    print(<span style="color:#e6db74">&#34;添加&#34;</span> <span style="color:#f92672">+</span> score.toString() <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;%&#34;</span>);
  }
}

<span style="color:#75715e">//创建实现化部分
</span><span style="color:#75715e"></span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Milk</span> <span style="color:#66d9ef">implements</span> ICoffeeAdditives {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> addSomething() {
    print(<span style="color:#e6db74">&#34;加奶&#34;</span>);
  }
}

<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Sugar</span> <span style="color:#66d9ef">implements</span> ICoffeeAdditives {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> addSomething() {
    print(<span style="color:#e6db74">&#34;加糖&#34;</span>);
  }
}

<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">LargeCoffee</span> <span style="color:#66d9ef">extends</span> RefinedCoffee {
  LargeCoffee(ICoffeeAdditives additives) <span style="color:#f92672">:</span> <span style="color:#66d9ef">super</span>(additives);

  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> orderCoffee(<span style="color:#66d9ef">int</span> count) {
    additives.addSomething();
    print(<span style="color:#e6db74">&#34;大杯咖啡&#34;</span> <span style="color:#f92672">+</span> count.toString() <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;杯&#34;</span>);
  }
}
<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">MidCoffee</span> <span style="color:#66d9ef">extends</span> RefinedCoffee {
  MidCoffee(ICoffeeAdditives additives) <span style="color:#f92672">:</span> <span style="color:#66d9ef">super</span>(additives);

  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> orderCoffee(<span style="color:#66d9ef">int</span> count) {
    additives.addSomething();
    print(<span style="color:#e6db74">&#34;中杯咖啡&#34;</span> <span style="color:#f92672">+</span> count.toString() <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;杯&#34;</span>);
  }
}
<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">RunBridge</span> <span style="color:#66d9ef">implements</span> Run {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">String</span> name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;桥接模式&#34;</span>;

  <span style="color:#960050;background-color:#1e0010">@</span>override
  main() {
    RefinedCoffee largeWithMilk <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> LargeCoffee(Milk());
    largeWithMilk.orderCoffee(<span style="color:#ae81ff">2</span>);
    largeWithMilk.checkQuality(<span style="color:#ae81ff">90</span>);
    print(<span style="color:#e6db74">&#34;</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">&#34;</span>);
    RefinedCoffee largeWithSugar <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> MidCoffee(Sugar());
    largeWithSugar.orderCoffee(<span style="color:#ae81ff">1</span>);
    largeWithSugar.checkQuality(<span style="color:#ae81ff">100</span>);
  }
}
</code></pre></div><h2 id="装饰器模式decorator-pattern">装饰器模式(Decorator Pattern)</h2>
<h3 id="模式分析-6">模式分析</h3>
<p>装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能，同时又不改变其结构。这种类型的设计模式属于结构型模式，它是作为现有的类的一个包装。</p>
<p>这种模式创建了一个装饰类，用来包装原有的类，并在保持类方法签名完整性的前提下，提供了额外的功能。</p>
<p>我们通过下面的实例来演示装饰器模式的用法。其中，我们将把一个形状装饰上不同的颜色，同时又不改变形状类。</p>
<h3 id="模式难点-5">模式难点</h3>
<p>实现现有抽象对象并传入已实现的抽象对象，并加入自定义方法</p>
<h3 id="模式解决问题-6">模式解决问题</h3>
<p>一般的，我们为了扩展一个类经常使用继承方式实现，由于继承为类引入静态特征，并且随着扩展功能的增多，子类会很膨胀。</p>
<h3 id="优点-6">优点</h3>
<p>装饰类和被装饰类可以独立发展，不会相互耦合，装饰模式是继承的一个替代模式，装饰模式可以动态扩展一个实现类的功能。</p>
<h3 id="缺点-6">缺点</h3>
<p>多层装饰比较复杂。</p>
<h3 id="模式应用场景-6">模式应用场景</h3>
<ol>
<li>扩展一个类的功能。</li>
<li>动态增加功能，动态撤销。</li>
</ol>
<h3 id="模式代码-6">模式代码</h3>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-dart" data-lang="dart"><span style="color:#75715e">//创建接口
</span><span style="color:#75715e"></span><span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Shape</span> {
  <span style="color:#66d9ef">void</span> draw();
}

<span style="color:#75715e">//创建接口实体类
</span><span style="color:#75715e"></span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Rectangle</span> <span style="color:#66d9ef">implements</span> Shape {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> draw() {
    print(<span style="color:#e6db74">&#34;shape: Rectangle&#34;</span>);
  }
}

<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Circle</span> <span style="color:#66d9ef">implements</span> Shape {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> draw() {
    print(<span style="color:#e6db74">&#34;shape: Circle&#34;</span>);
  }
}

<span style="color:#75715e">//创建实现了Shape接口的抽象类
</span><span style="color:#75715e"></span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">ShapeDecorator</span> <span style="color:#66d9ef">implements</span> Shape {
  <span style="color:#66d9ef">final</span> Shape decoratedShape;
  ShapeDecorator(<span style="color:#66d9ef">this</span>.decoratedShape);
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> draw() {
    decoratedShape.draw();
  }
}

<span style="color:#75715e">//创建扩展了 ShapeDecorator 类的实体装饰类。
</span><span style="color:#75715e"></span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">RedShapeDecorator</span> <span style="color:#66d9ef">extends</span> ShapeDecorator {
  RedShapeDecorator(Shape decoratedShape) <span style="color:#f92672">:</span> <span style="color:#66d9ef">super</span>(decoratedShape);
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> draw() {
    decoratedShape.draw();
    _setRedBorder(decoratedShape);
  }

  <span style="color:#66d9ef">void</span> _setRedBorder(Shape decoratedShape) {
    print(<span style="color:#e6db74">&#34;Border Color: Red&#34;</span>);
  }
}
<span style="color:#75715e">//使用 RedShapeDecorator 来装饰 Shape 对象。
</span><span style="color:#75715e"></span>
<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">RunDecorator</span> <span style="color:#66d9ef">implements</span> Run {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> main() {
    Shape circle <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> Circle();
    <span style="color:#75715e">// ShapeDecorator redCircle = new RedShapeDecorator(new Circle());
</span><span style="color:#75715e"></span>    <span style="color:#75715e">// ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());
</span><span style="color:#75715e"></span>    Shape redCircle <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> RedShapeDecorator(<span style="color:#66d9ef">new</span> Circle());
    Shape redRectangle <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> RedShapeDecorator(<span style="color:#66d9ef">new</span> Rectangle());
    print(<span style="color:#e6db74">&#34;Circle with normal border&#34;</span>);
    circle.draw();

    print(<span style="color:#e6db74">&#34;</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">Circle of red border&#34;</span>);
    redCircle.draw();

    print(<span style="color:#e6db74">&#34;</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">Rectangle of red border&#34;</span>);
    redRectangle.draw();
  }

  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">String</span> name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;装饰器模式&#34;</span>;
}
</code></pre></div><h2 id="外观模式facade">外观模式(Facade)</h2>
<h3 id="模式分析-7">模式分析</h3>
<p>外观模式(Facade Pattern)隐藏系统的复杂性，并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式，它向现有的系统添加一个接口，来隐藏系统的复杂性。</p>
<p>这种模式涉及到一个单一的类，该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。</p>
<h3 id="模式难点-6">模式难点</h3>
<h3 id="模式解决问题-7">模式解决问题</h3>
<p>降低访问复杂系统的内部子系统时的复杂度，简化客户端与之的接口。</p>
<h3 id="优点-7">优点</h3>
<ol>
<li>减少系统相互依赖。</li>
<li>提高灵活性。</li>
<li>提高了安全性。</li>
</ol>
<h3 id="缺点-7">缺点</h3>
<p>不符合开闭原则，如果要改东西很麻烦，继承重写都不合适。</p>
<h3 id="模式应用场景-7">模式应用场景</h3>
<ol>
<li>为复杂的模块或子系统提供外界访问的模块。</li>
<li>子系统相对独立。</li>
<li>预防低水平人员带来的风险。</li>
</ol>
<h3 id="模式代码-7">模式代码</h3>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-dart" data-lang="dart"><span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Shape</span> {
  <span style="color:#66d9ef">void</span> draw();
}

<span style="color:#75715e">// 创建实现接口的实体类。
</span><span style="color:#75715e"></span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Rectangle</span> <span style="color:#66d9ef">implements</span> Shape {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> draw() {
    print(<span style="color:#e6db74">&#34;Rectangle::draw()&#34;</span>);
  }
}

<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Square</span> <span style="color:#66d9ef">implements</span> Shape {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> draw() {
    print(<span style="color:#e6db74">&#34;Square::draw()&#34;</span>);
  }
}

<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Circle</span> <span style="color:#66d9ef">implements</span> Shape {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> draw() {
    print(<span style="color:#e6db74">&#34;Circle::draw()&#34;</span>);
  }
}

<span style="color:#75715e">// 创建一个外观类。
</span><span style="color:#75715e"></span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">ShapeMaker</span> {
  Shape circle;
  Shape rectangle;
  Shape square;

  ShapeMaker() {
    circle <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> Circle();
    rectangle <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> Rectangle();
    square <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> Square();
  }

  <span style="color:#66d9ef">void</span> drawCircle() {
    circle.draw();
  }

  <span style="color:#66d9ef">void</span> drawRectangle() {
    rectangle.draw();
  }

  <span style="color:#66d9ef">void</span> drawSquare() {
    square.draw();
  }
}

<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">RunFacade</span> <span style="color:#66d9ef">implements</span> Run {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> main() {
    ShapeMaker shapeMaker <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> ShapeMaker();
    shapeMaker.drawCircle();
    shapeMaker.drawRectangle();
    shapeMaker.drawSquare();
  }

  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">String</span> name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;外观模式&#34;</span>;
}
</code></pre></div><h2 id="享元模式flyweight">享元模式(Flyweight)</h2>
<h3 id="模式分析-8">模式分析</h3>
<p>享元模式(Flyweight Pattern)主要用于减少创建对象的数量，以减少内存占用和提高性能。这种类型的设计模式属于结构型模式，它提供了减少对象数量从而改善应用所需的对象结构的方式。</p>
<p>享元模式尝试重用现有的同类对象，如果未找到匹配的对象，则创建新对象。我们将通过创建 5 个对象来画出 20 个分布于不同位置的圆来演示这种模式。由于只有 5 种可用的颜色，所以 color 属性被用来检查现有的 Circle 对象。</p>
<h3 id="模式难点-7">模式难点</h3>
<p>使用Map讲重复创建的对象进行存储，需要严格分离出外部状态和内部状态</p>
<h3 id="模式解决问题-8">模式解决问题</h3>
<p>在有大量对象时，有可能会造成内存溢出，我们把其中共同的部分抽象出来，如果有相同的业务请求，直接返回在内存中已有的对象，避免重新创建。</p>
<h3 id="优点-8">优点</h3>
<p>大大减少对象的创建，降低系统的内存，使效率提高。</p>
<h3 id="缺点-8">缺点</h3>
<p>提高了系统的复杂度，需要分离出外部状态和内部状态，而且外部状态具有固有化的性质，不应该随着内部状态的变化而变化，否则会造成系统的混乱。</p>
<h3 id="模式应用场景-8">模式应用场景</h3>
<ol>
<li>系统有大量相似对象。</li>
<li>需要缓冲池的场景。</li>
</ol>
<h3 id="模式代码-8">模式代码</h3>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-dart" data-lang="dart"><span style="color:#66d9ef">import</span> <span style="color:#e6db74">&#39;dart:math&#39;</span> <span style="color:#66d9ef">as</span> math;

<span style="color:#66d9ef">import</span> <span style="color:#e6db74">&#39;run.dart&#39;</span>;

<span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Shape</span> {
  <span style="color:#66d9ef">void</span> draw();
}

<span style="color:#75715e">// 创建实现接口的实体类。
</span><span style="color:#75715e"></span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Circle</span> <span style="color:#66d9ef">implements</span> Shape {
  <span style="color:#66d9ef">String</span> color;
  <span style="color:#66d9ef">int</span> x;
  <span style="color:#66d9ef">int</span> y;
  <span style="color:#66d9ef">int</span> radius;
  Circle(<span style="color:#66d9ef">String</span> color) {
    <span style="color:#66d9ef">this</span>.color <span style="color:#f92672">=</span> color;
  }
  <span style="color:#66d9ef">void</span> setX(<span style="color:#66d9ef">int</span> x) {
    <span style="color:#66d9ef">this</span>.x <span style="color:#f92672">=</span> x;
  }

  <span style="color:#66d9ef">void</span> setY(<span style="color:#66d9ef">int</span> y) {
    <span style="color:#66d9ef">this</span>.y <span style="color:#f92672">=</span> y;
  }

  <span style="color:#66d9ef">void</span> setRadius(<span style="color:#66d9ef">int</span> radius) {
    <span style="color:#66d9ef">this</span>.radius <span style="color:#f92672">=</span> radius;
  }

  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> draw() {
    print(<span style="color:#e6db74">&#34;Circle: Draw() [Color : &#34;</span> <span style="color:#f92672">+</span>
        color <span style="color:#f92672">+</span>
        <span style="color:#e6db74">&#34;, x : &#34;</span> <span style="color:#f92672">+</span>
        x.toString() <span style="color:#f92672">+</span>
        <span style="color:#e6db74">&#34;, y :&#34;</span> <span style="color:#f92672">+</span>
        y.toString() <span style="color:#f92672">+</span>
        <span style="color:#e6db74">&#34;, radius :&#34;</span> <span style="color:#f92672">+</span>
        radius.toString());
  }
}

<span style="color:#75715e">// 创建一个工厂，生成基于给定信息的实体类的对象。
</span><span style="color:#75715e"></span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">ShapeFactory</span> {
  <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">final</span> Map<span style="color:#f92672">&lt;</span><span style="color:#66d9ef">String</span>, Shape<span style="color:#f92672">&gt;</span> circleMap <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> Map();

  <span style="color:#66d9ef">static</span> Shape getCircle(<span style="color:#66d9ef">String</span> color) {
    Circle circle <span style="color:#f92672">=</span> circleMap[color];

    <span style="color:#66d9ef">if</span> (circle <span style="color:#f92672">==</span> <span style="color:#66d9ef">null</span>) {
      circle <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> Circle(color);
      circleMap[color] <span style="color:#f92672">=</span> circle;
      print(<span style="color:#e6db74">&#34;Creating circle of color : &#34;</span> <span style="color:#f92672">+</span> color);
    }
    <span style="color:#66d9ef">return</span> circle;
  }
}

<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">RunFlyweight</span> <span style="color:#66d9ef">implements</span> Run {
  <span style="color:#66d9ef">final</span> List<span style="color:#f92672">&lt;</span><span style="color:#66d9ef">String</span><span style="color:#f92672">&gt;</span> colors <span style="color:#f92672">=</span> [<span style="color:#e6db74">&#34;Red&#34;</span>, <span style="color:#e6db74">&#34;Green&#34;</span>, <span style="color:#e6db74">&#34;Blue&#34;</span>, <span style="color:#e6db74">&#34;White&#34;</span>, <span style="color:#e6db74">&#34;Black&#34;</span>];
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> main() {
    <span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">int</span> i <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>; i <span style="color:#f92672">&lt;</span> <span style="color:#ae81ff">20</span>; <span style="color:#f92672">++</span>i) {
      Circle circle <span style="color:#f92672">=</span> ShapeFactory.getCircle(getRandomColor());
      circle.setX(getRandomX());
      circle.setY(getRandomY());
      circle.setRadius(<span style="color:#ae81ff">100</span>);
      circle.draw();
    }
  }

  <span style="color:#66d9ef">String</span> getRandomColor() {
    <span style="color:#66d9ef">return</span> colors[math.Random().nextInt(colors.length)];
  }

  <span style="color:#66d9ef">int</span> getRandomX() {
    <span style="color:#66d9ef">return</span> math.Random().nextInt(<span style="color:#ae81ff">100</span>);
  }

  <span style="color:#66d9ef">int</span> getRandomY() {
    <span style="color:#66d9ef">return</span> math.Random().nextInt(<span style="color:#ae81ff">100</span>);
  }

  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">String</span> name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;享元模式&#34;</span>;
}
</code></pre></div><h2 id="代理模式">代理模式</h2>
<h3 id="模式分析-9">模式分析</h3>
<p>在代理模式(Proxy Pattern)中，一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。</p>
<p>在代理模式中，我们创建具有现有对象的对象，以便向外界提供功能接口。</p>
<h3 id="模式难点-8">模式难点</h3>
<h3 id="模式解决问题-9">模式解决问题</h3>
<p>在直接访问对象时带来的问题，比如说：要访问的对象在远程的机器上。在面向对象系统中，有些对象由于某些原因(比如对象创建开销很大，或者某些操作需要安全控制，或者需要进程外的访问)，直接访问会给使用者或者系统结构带来很多麻烦，我们可以在访问此对象时加上一个对此对象的访问层。</p>
<h3 id="优点-9">优点</h3>
<ol>
<li>你可以在客户端毫无察觉的情况下控制服务对象。</li>
<li>如果客户端对服务对象的生命周期没有特殊要求， 你可以对生命周期进行管理。</li>
<li>即使服务对象还未准备好或不存在， 代理也可以正常工作。</li>
<li>开闭原则。 你可以在不对服务或客户端做出修改的情况下创建新代理。</li>
</ol>
<h3 id="缺点-9">缺点</h3>
<ol>
<li>由于在客户端和真实主题之间增加了代理对象，因此有些类型的代理模式可能会造成请求的处理速度变慢。</li>
<li>实现代理模式需要额外的工作，有些代理模式的实现非常复杂。</li>
</ol>
<h3 id="模式应用场景-9">模式应用场景</h3>
<p>按职责来划分，通常有以下使用场景：</p>
<ol>
<li>本地执行远程服务 (远程代理)。 适用于服务对象位于远程服务器上的情形。</li>
<li>延迟初始化 (虚拟代理)。 如果你有一个偶尔使用的重量级服务对象， 一直保持该对象运行会消耗系统资源时， 可使用代理模式。</li>
<li>Copy-on-Write 代理。</li>
<li>访问控制 (保护代理)。 如果你只希望特定客户端使用服务对象， 这里的对象可以是操作系统中非常重要的部分， 而客户端则是各种已启动的程序 (包括恶意程序)， 此时可使用代理模式。</li>
<li>Cache代理。</li>
<li>防火墙(Firewall)代理。</li>
<li>同步化(Synchronization)代理。</li>
<li>智能引用(Smart Reference)代理。 可在没有客户端使用某个重量级对象时立即销毁该对象。</li>
<li>记录日志请求 (日志记录代理)。 适用于当你需要保存对于服务对象的请求历史记录时。 代理可以在向服务传递请求前进行记录。</li>
</ol>
<h3 id="模式代码-9">模式代码</h3>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-dart" data-lang="dart"><span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Subject</span> {
  <span style="color:#66d9ef">void</span> request();
}

<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">RealSubject</span> <span style="color:#66d9ef">implements</span> Subject {
  <span style="color:#66d9ef">const</span> RealSubject();
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> request() {
    print(<span style="color:#e6db74">&#34;RealSubject:正在连接&#34;</span>);
  }
}

<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">SubjectProxy</span> <span style="color:#66d9ef">implements</span> Subject {
  <span style="color:#66d9ef">final</span> RealSubject _realSubject;
  <span style="color:#66d9ef">const</span> SubjectProxy(<span style="color:#66d9ef">this</span>._realSubject);
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> request() {
    <span style="color:#66d9ef">if</span> (<span style="color:#66d9ef">this</span>._checkAccess()) {
      <span style="color:#66d9ef">this</span>._realSubject.request();
      <span style="color:#66d9ef">this</span>._logAccess();
    }
  }

  <span style="color:#66d9ef">bool</span> _checkAccess() {
    print(<span style="color:#e6db74">&#34;Proxy: 判断当前是否可连接&#34;</span>);
    <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">true</span>;
  }

  <span style="color:#66d9ef">void</span> _logAccess() {
    print(<span style="color:#e6db74">&#34;Proxy: 写一些日志比如连接时间&#34;</span>);
  }
}

<span style="color:#66d9ef">class</span> <span style="color:#a6e22e">RunProxy</span> <span style="color:#66d9ef">implements</span> Run {
  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">void</span> main() {
    print(<span style="color:#e6db74">&#39;Client: 使用RealSubject类：&#39;</span>);
    <span style="color:#66d9ef">const</span> realSubject <span style="color:#f92672">=</span> <span style="color:#66d9ef">const</span> RealSubject();
    _clientCode(realSubject);
    print(<span style="color:#e6db74">&#39;&#39;</span>);
    print(<span style="color:#e6db74">&#39;Client: 使用代理类：&#39;</span>);
    <span style="color:#66d9ef">const</span> proxy <span style="color:#f92672">=</span> <span style="color:#66d9ef">const</span> SubjectProxy(realSubject);
    _clientCode(proxy);
  }

  _clientCode(Subject subject) {
    <span style="color:#75715e">// ...
</span><span style="color:#75715e"></span>    print(<span style="color:#e6db74">&#39;做一些连接前的事情&#39;</span>);
    subject.request();

    <span style="color:#75715e">// ...
</span><span style="color:#75715e"></span>  }

  <span style="color:#960050;background-color:#1e0010">@</span>override
  <span style="color:#66d9ef">String</span> name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;代理模式&#34;</span>;
}
</code></pre></div><h2 id="发布订阅模式">发布订阅模式</h2>
<h3 id="模式分析-10">模式分析</h3>
<h3 id="模式难点-9">模式难点</h3>
<h3 id="模式解决问题-10">模式解决问题</h3>
<h3 id="优点-10">优点</h3>
<h3 id="缺点-10">缺点</h3>
<h3 id="模式应用场景-10">模式应用场景</h3>
<h3 id="模式代码-10">模式代码</h3>
        </div>

        
<div class="post-archive">
    <ul class="post-copyright">
        <li><strong>原文作者：</strong><a rel="author" href="https://luckly.work/">luckly</a></li>
        <li style="word-break:break-all"><strong>原文链接：</strong><a href="https://luckly.work/post/dart/dart%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80%E4%B9%8B%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">https://luckly.work/post/dart/dart%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80%E4%B9%8B%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</a></li>
        <li><strong>版权声明：</strong>本作品采用<a rel="license" href="https://creativecommons.org/licenses/by-nc-nd/4.0/">知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议</a>进行许可，非商业转载请注明出处（作者，原文链接），商业转载请联系作者获得授权。</li>
    </ul>
</div>
<br/>



        

<div class="post-archive">
    <h2>See Also</h2>
    <ul class="listing">
        
        <li><a href="/post/python/dart%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80%E4%B9%8B%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">《Dart语言基础之设计模式》</a></li>
        
        <li><a href="/post/dart/dart%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80%E4%B9%8BString/">《Dart语言基础之String》</a></li>
        
        <li><a href="/post/Flutter/flutter%E4%B8%ADkey%E7%9A%84%E4%BD%9C%E7%94%A8/">《Flutter中key的作用》</a></li>
        
        <li><a href="/post/Flutter/%E5%9C%A8Flutter%E4%B8%AD%E5%88%A9%E7%94%A8Firebase%E6%8F%92%E4%BB%B6%E8%BF%9B%E8%A1%8C%E7%94%A8%E6%88%B7%E8%BA%AB%E4%BB%BD%E9%AA%8C%E8%AF%81%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F/">《在Flutter中利用Firebase插件进行用户身份验证应用程序》</a></li>
        
        <li><a href="/post/Flutter/%E5%9C%A8Flutter%E4%B8%AD%E5%88%B6%E4%BD%9C%E8%AE%A1%E6%97%B6%E5%99%A8%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F/">《在Flutter中制作计时器应用程序》</a></li>
        
    </ul>
</div>


        <div class="post-meta meta-tags">
            
            <ul class="clearfix">
                
                <li><a href='/tags/Flutter'>Flutter</a></li>
                
            </ul>
            
        </div>
    </article>
    
    

    
    
    <div class="post bg-white">
      <script src="https://utteranc.es/client.js"
            repo= "https://github.com/ITmxs/repo"
            issue-term="pathname"
            theme="github-light"
            crossorigin="anonymous"
            async>
      </script>
    </div>
    
</div>

                    <footer id="footer">
    <div>
        &copy; 2021 <a href="https://luckly.work/">早起的年轻人 By luckly</a>
        
        | <a rel="nofollow" target="_blank" href="http://beian.miit.gov.cn/">粤ICP备2021号-1</a>
        
    </div>
    <br />
    <div>
        <div class="github-badge">
            <a href="https://juejin.cn/user/3843548384077192" target="_black" rel="nofollow"><span class="badge-subject">Powered by</span><span class="badge-value bg-blue">掘金</span></a>
        </div>
        <div class="github-badge">
            <a href="https://space.bilibili.com/480883651" target="_black"><span class="badge-subject">Design by</span><span class="badge-value bg-brightgreen">早起的年轻人</span></a>
        </div>
        <div class="github-badge">
            <a href="https://cloud.tencent.com/developer/user/6702670" target="_black"><span class="badge-subject">Theme</span><span class="badge-value bg-yellowgreen">云社区</span></a>
        </div>
    </div>
</footer>


    
    <script type="text/javascript">
        window.MathJax = {
            tex2jax: {
                inlineMath: [['$', '$']],
                processEscapes: true
                }
            };
    </script>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML' async></script><script src="https://cdn.bootcdn.net/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.js"></script>

<a id="rocket" href="#top"></a>
<script type="text/javascript" src='/js/totop.js?v=0.0.0' async=""></script>



    <script type="text/javascript" src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" async></script>




    <script src='/js/douban.js'></script>
    <script src="/js/copy-to-clipboard.js"></script>

                </div>

                <div id="secondary">
    <section class="widget">
        <form id="search" action='https://luckly.work/search/' method="get" accept-charset="utf-8" target="_blank" _lpchecked="1">
      
      <input type="text" name="q" maxlength="20" placeholder="Search">
      <input type="hidden" name="sitesearch" value="https://luckly.work/">
      <button type="submit" class="submit icon-search"></button>
</form>
    </section>
    
    <section class="widget">
        <h3 class="widget-title">最近文章</h3>
<ul class="widget-list">
    
    <li>
        <a href="https://luckly.work/post/nginx/nginx%E6%96%87%E4%BB%B6%E5%86%85%E5%AE%B9/" title="Nginx文件内容">Nginx文件内容</a>
    </li>
    
    <li>
        <a href="https://luckly.work/post/nginx/nginx%E6%9E%81%E7%AE%80%E6%95%99%E7%A8%8B/" title="Nginx极简教程">Nginx极简教程</a>
    </li>
    
    <li>
        <a href="https://luckly.work/post/nginx/%E5%8D%81%E5%88%86%E9%92%9F%E5%85%A5%E9%97%A8nginx/" title="十分钟入门Nginx">十分钟入门Nginx</a>
    </li>
    
    <li>
        <a href="https://luckly.work/post/go/Goland%E8%BF%9C%E7%A8%8B%E5%BC%80%E5%8F%91%E9%85%8D%E7%BD%AE/" title="Goland远程开发配置">Goland远程开发配置</a>
    </li>
    
    <li>
        <a href="https://luckly.work/post/%E8%AF%BB%E4%B9%A6/%E5%9F%9F%E5%90%8D%E8%A7%A3%E6%9E%90/" title="域名解析">域名解析</a>
    </li>
    
    <li>
        <a href="https://luckly.work/post/git/%E6%8F%90%E4%BA%A4%E8%BF%87%E7%A8%8B%E7%9C%81%E7%95%A5%E6%9F%90%E4%BA%9B%E6%96%87%E4%BB%B6/" title="提交过程省略某些文件">提交过程省略某些文件</a>
    </li>
    
    <li>
        <a href="https://luckly.work/post/flutter_tips/Flutter_DropdownButton%E7%A4%BA%E4%BE%8B/" title="Flutter_DropdownButton示例">Flutter_DropdownButton示例</a>
    </li>
    
    <li>
        <a href="https://luckly.work/post/flutter_tips/Flutter_ExpansionPanelList%E5%92%8CExpansionPanelList.radio%E7%A4%BA%E4%BE%8B/" title="Flutter_ExpansionPanelList和ExpansionPanelList">Flutter_ExpansionPanelList和ExpansionPanelList</a>
    </li>
    
    <li>
        <a href="https://luckly.work/post/flutter_tips/Flutter%E5%BE%AE%E4%BF%A1%E5%88%86%E4%BA%AB%E9%93%BE%E6%8E%A5%E8%B7%B3%E5%9B%9EApp%E6%8C%87%E5%AE%9A%E9%A1%B5%E9%9D%A2/" title="Flutter微信分享链接跳回App指定页面">Flutter微信分享链接跳回App指定页面</a>
    </li>
    
    <li>
        <a href="https://luckly.work/post/%E4%BF%A1%E6%81%AF%E7%B3%BB%E7%BB%9F/%E5%A4%96%E5%8C%85%E5%8F%AF%E8%83%BD%E7%9A%84%E9%97%AE%E9%A2%98/" title="外包可能的问题">外包可能的问题</a>
    </li>
    
</ul>
    </section>

    

    <section class="widget">
        <h3 class="widget-title"><a href='/categories/'>分类</a></h3>
<ul class="widget-list">
    
    <li><a href="https://luckly.work/categories/Flutter/">Flutter (326)</a></li>
    
    <li><a href="https://luckly.work/categories/IT/">IT (2)</a></li>
    
    <li><a href="https://luckly.work/categories/Kotlin/">Kotlin (2)</a></li>
    
    <li><a href="https://luckly.work/categories/Mysql/">Mysql (1)</a></li>
    
    <li><a href="https://luckly.work/categories/nginx/">nginx (1)</a></li>
    
    <li><a href="https://luckly.work/categories/Vue/">Vue (6)</a></li>
    
    <li><a href="https://luckly.work/categories/YouTube%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD/">YouTube视频下载 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/android/">android (6)</a></li>
    
    <li><a href="https://luckly.work/categories/dart/">dart (96)</a></li>
    
    <li><a href="https://luckly.work/categories/Flutter/">Flutter (28)</a></li>
    
    <li><a href="https://luckly.work/categories/gin/">gin (25)</a></li>
    
    <li><a href="https://luckly.work/categories/git/">git (4)</a></li>
    
    <li><a href="https://luckly.work/categories/Go/">Go (102)</a></li>
    
    <li><a href="https://luckly.work/categories/gorm/">gorm (4)</a></li>
    
    <li><a href="https://luckly.work/categories/grpc/">grpc (1)</a></li>
    
    <li><a href="https://luckly.work/categories/html/">html (3)</a></li>
    
    <li><a href="https://luckly.work/categories/ios/">ios (1)</a></li>
    
    <li><a href="https://luckly.work/categories/linux/">linux (1)</a></li>
    
    <li><a href="https://luckly.work/categories/nginx/">nginx (6)</a></li>
    
    <li><a href="https://luckly.work/categories/python/">python (35)</a></li>
    
    <li><a href="https://luckly.work/categories/read/">读书笔记 (6)</a></li>
    
    <li><a href="https://luckly.work/categories/redis/">redis (2)</a></li>
    
    <li><a href="https://luckly.work/categories/%E4%B8%AA%E4%BA%BA%E8%B5%84%E6%96%99/">个人资料 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E4%B9%A6%E5%8D%95/">书单 (8)</a></li>
    
    <li><a href="https://luckly.work/categories/%E4%B9%A6%E8%AF%84/">书评 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E4%BF%A1%E6%81%AF%E7%B3%BB%E7%BB%9F%E7%AE%A1%E7%90%86%E5%B8%88/">信息系统管理师 (19)</a></li>
    
    <li><a href="https://luckly.work/categories/%E4%BF%A1%E6%81%AF%E7%B3%BB%E7%BB%9F%E9%A1%B9%E7%9B%AE%E7%AE%A1%E7%90%86%E5%B8%88/">信息系统项目管理师 (25)</a></li>
    
    <li><a href="https://luckly.work/categories/%E5%8E%9F%E5%88%99/">原则 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E5%8E%9F%E7%94%9F%E9%80%9A%E8%AE%AF/">原生通讯 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E5%9F%BA%E7%A1%80/">基础 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E5%A4%8D%E5%88%A9%E6%95%88%E5%BA%94/">复利效应 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/">安装教程 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E5%B0%91%E6%9C%89%E4%BA%BA%E8%B5%B0%E7%9A%84%E8%B7%AF/">少有人走的路 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E5%BF%83%E8%AF%AD/">心语 (3)</a></li>
    
    <li><a href="https://luckly.work/categories/%E6%8F%92%E4%BB%B6/">插件 (2)</a></li>
    
    <li><a href="https://luckly.work/categories/%E6%95%99%E5%AD%A6/">教学 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E7%8E%8B%E9%98%B3%E6%98%8E/">王阳明 (3)</a></li>
    
    <li><a href="https://luckly.work/categories/%E7%94%B5%E5%AD%90%E4%B9%A6/">电子书 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E7%99%BB%E9%99%86%E8%A1%A8%E5%8D%95/">登陆表单 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E7%A8%BB%E7%9B%9B%E5%92%8C%E5%A4%AB/">稻盛和夫 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E7%A9%B7%E7%88%B8%E7%88%B8%E5%AF%8C%E7%88%B8%E7%88%B8/">穷爸爸富爸爸 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E7%B2%BE%E8%BF%9B/">精进 (3)</a></li>
    
    <li><a href="https://luckly.work/categories/%E7%BC%96%E7%A8%8B/">编程 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E8%99%9A%E5%B9%BB/">虚幻 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E8%B4%A2%E5%8A%A1%E8%87%AA%E7%94%B1%E4%B9%8B%E8%B7%AF/">财务自由之路 (2)</a></li>
    
    <li><a href="https://luckly.work/categories/%E8%B7%91%E6%AD%A5/">跑步 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E8%B7%AF%E7%94%B1%E4%BC%A0%E5%8F%82/">路由传参 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E8%B7%AF%E7%BA%BF/">路线 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E8%BD%AF%E4%BB%B6%E5%AE%9E%E6%96%BD/">软件实施 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E9%98%B3%E6%98%8E%E5%BF%83%E5%AD%A6/">阳明心学 (3)</a></li>
    
    <li><a href="https://luckly.work/categories/%E9%A1%B9%E7%9B%AE/">项目 (1)</a></li>
    
    <li><a href="https://luckly.work/categories/%E9%AD%85%E5%8A%9B/">魅力 (1)</a></li>
    
</ul>
    </section>

    <section class="widget">
        <h3 class="widget-title"><a href='/tags/'>标签</a></h3>
<div class="tagcloud">
    
    <a href="https://luckly.work/tags/flutter/">flutter</a>
    
    <a href="https://luckly.work/tags/IT/">IT</a>
    
    <a href="https://luckly.work/tags/Kotlin/">Kotlin</a>
    
    <a href="https://luckly.work/tags/Mysql/">Mysql</a>
    
    <a href="https://luckly.work/tags/nginx/">nginx</a>
    
    <a href="https://luckly.work/tags/Vue/">Vue</a>
    
    <a href="https://luckly.work/tags/YouTube%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD/">YouTube视频下载</a>
    
    <a href="https://luckly.work/tags/android/">android</a>
    
    <a href="https://luckly.work/tags/dart/">dart</a>
    
    <a href="https://luckly.work/tags/flutter/">flutter</a>
    
    <a href="https://luckly.work/tags/gin/">gin</a>
    
    <a href="https://luckly.work/tags/git/">git</a>
    
    <a href="https://luckly.work/tags/go/">go</a>
    
    <a href="https://luckly.work/tags/gorm/">gorm</a>
    
    <a href="https://luckly.work/tags/grpc/">grpc</a>
    
    <a href="https://luckly.work/tags/html/">html</a>
    
    <a href="https://luckly.work/tags/ios/">ios</a>
    
    <a href="https://luckly.work/tags/linux/">linux</a>
    
    <a href="https://luckly.work/tags/nginx/">nginx</a>
    
    <a href="https://luckly.work/tags/python/">python</a>
    
    <a href="https://luckly.work/tags/redis/">redis</a>
    
    <a href="https://luckly.work/tags/%E4%B8%AA%E4%BA%BA%E8%B5%84%E6%96%99/">个人资料</a>
    
    <a href="https://luckly.work/tags/%E4%B9%A6%E5%8D%95/">书单</a>
    
    <a href="https://luckly.work/tags/%E4%B9%A6%E8%AF%84/">书评</a>
    
    <a href="https://luckly.work/tags/%E4%BF%A1%E6%81%AF%E7%B3%BB%E7%BB%9F%E7%AE%A1%E7%90%86%E5%B8%88/">信息系统管理师</a>
    
    <a href="https://luckly.work/tags/%E4%BF%A1%E6%81%AF%E7%B3%BB%E7%BB%9F%E9%A1%B9%E7%9B%AE%E7%AE%A1%E7%90%86%E5%B8%88/">信息系统项目管理师</a>
    
    <a href="https://luckly.work/tags/%E5%85%A5%E9%97%A8/">入门</a>
    
    <a href="https://luckly.work/tags/%E5%8E%9F%E5%88%99/">原则</a>
    
    <a href="https://luckly.work/tags/%E5%8E%9F%E7%94%9F%E9%80%9A%E8%AE%AF/">原生通讯</a>
    
    <a href="https://luckly.work/tags/%E5%9F%BA%E7%A1%80/">基础</a>
    
    <a href="https://luckly.work/tags/%E5%A4%8D%E5%88%A9%E6%95%88%E5%BA%94/">复利效应</a>
    
    <a href="https://luckly.work/tags/%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/">安装教程</a>
    
    <a href="https://luckly.work/tags/%E5%B0%91%E6%9C%89%E4%BA%BA%E8%B5%B0%E7%9A%84%E8%B7%AF/">少有人走的路</a>
    
    <a href="https://luckly.work/tags/%E5%BF%83%E8%AF%AD/">心语</a>
    
    <a href="https://luckly.work/tags/%E6%8F%92%E4%BB%B6/">插件</a>
    
    <a href="https://luckly.work/tags/%E6%95%99%E5%AD%A6/">教学</a>
    
    <a href="https://luckly.work/tags/%E7%8E%8B%E9%98%B3%E6%98%8E/">王阳明</a>
    
    <a href="https://luckly.work/tags/%E7%94%B5%E5%AD%90%E4%B9%A6/">电子书</a>
    
    <a href="https://luckly.work/tags/%E7%99%BB%E9%99%86%E8%A1%A8%E5%8D%95/">登陆表单</a>
    
    <a href="https://luckly.work/tags/%E7%A8%BB%E7%9B%9B%E5%92%8C%E5%A4%AB/">稻盛和夫</a>
    
    <a href="https://luckly.work/tags/%E7%A9%B7%E7%88%B8%E7%88%B8%E5%AF%8C%E7%88%B8%E7%88%B8/">穷爸爸富爸爸</a>
    
    <a href="https://luckly.work/tags/%E7%B2%BE%E8%BF%9B/">精进</a>
    
    <a href="https://luckly.work/tags/%E7%BC%96%E7%A8%8B/">编程</a>
    
    <a href="https://luckly.work/tags/%E8%99%9A%E5%B9%BB/">虚幻</a>
    
    <a href="https://luckly.work/tags/%E8%AF%97/">诗</a>
    
    <a href="https://luckly.work/tags/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/">读书笔记</a>
    
    <a href="https://luckly.work/tags/%E8%B4%A2%E5%8A%A1%E8%87%AA%E7%94%B1%E4%B9%8B%E8%B7%AF/">财务自由之路</a>
    
    <a href="https://luckly.work/tags/%E8%B7%91%E6%AD%A5/">跑步</a>
    
    <a href="https://luckly.work/tags/%E8%B7%AF%E7%94%B1%E4%BC%A0%E5%8F%82/">路由传参</a>
    
    <a href="https://luckly.work/tags/%E8%B7%AF%E7%BA%BF/">路线</a>
    
    <a href="https://luckly.work/tags/%E8%BD%AF%E4%BB%B6%E5%AE%9E%E6%96%BD/">软件实施</a>
    
    <a href="https://luckly.work/tags/%E9%80%9A%E8%AE%AF%E5%BD%95/">通讯录</a>
    
    <a href="https://luckly.work/tags/%E9%98%B3%E6%98%8E%E5%BF%83%E5%AD%A6/">阳明心学</a>
    
    <a href="https://luckly.work/tags/%E9%A1%B9%E7%9B%AE/">项目</a>
    
    <a href="https://luckly.work/tags/%E9%AD%85%E5%8A%9B/">魅力</a>
    
</div>
    </section>

    
<section class="widget">
    <h3 class="widget-title">友情链接</h3>
    <ul class="widget-list">
        
        <li>
            <a target="_blank" href="http://www.topgoer.com/" title="枯藤">枯藤</a>
        </li>
        
        <li>
            <a target="_blank" href="https://gorm.cn/zh_CN/docs/index.html" title="gorm">gorm</a>
        </li>
        
        <li>
            <a target="_blank" href="https://docs.python.org/zh-cn/3/tutorial/index.html" title="python">python</a>
        </li>
        
        <li>
            <a target="_blank" href="https://www.liwenzhou.com/" title="李文周">李文周的博客</a>
        </li>
        
        <li>
            <a target="_blank" href="http://www.xbzweb.com/" title="小包子的博客">小包子的博客</a>
        </li>
        
        <li>
            <a target="_blank" href="https://www.flysnow.org/" title="飞雪无情的博客">飞雪无情的博客</a>
        </li>
        
        <li>
            <a target="_blank" href="https://sliverhorn.com/" title="sliverhorn的博客">sliverhorn的博客</a>
        </li>
        
        <li>
            <a target="_blank" href="http://yuedu.baidu.com/ebook/14a722970740be1e640e9a3e" title="Android Gradle权威指南">Android Gradle权威指南</a>
        </li>
        
        <li>
            <a target="_blank" href="https://gesdh.cn/" title="小格子">格子导航</a>
        </li>
        
        <li>
            <a target="_blank" href="https://itachi.xyz/" title="阿林">itachi&#39;s Blog</a>
        </li>
        
        <li>
            <a target="_blank" href="https://darjun.github.io/" title="大俊">大俊Blog</a>
        </li>
        
        <li>
            <a target="_blank" href="https://geektutu.com/post/quick-golang.html" title="极客兔兔">极客兔兔Blog</a>
        </li>
        
        <li>
            <a target="_blank" href="http://zxfcumtcs.github.io/" title="赵雪峰">雪峰Blog</a>
        </li>
        
    </ul>
</section>


    <section class="widget">
        <h3 class="widget-title">其它</h3>
        <ul class="widget-list">
            <li><a href="https://luckly.work/index.xml">文章 RSS</a></li>
        </ul>
    </section>
</div>
            </div>
        </div>
    </div>
</body>

</html>